import { apiLogin } from "@/api/sys";
import type { RoleInfo, UserInfo } from "@/models";
import { router } from "@/router";
import { store } from "@/stores";
import { tokenCache, userInfoCache } from "@/utils/cache";
import { defineStore, type StateTree } from "pinia";
import { computed, reactive, toRefs } from "vue";

interface UserState extends StateTree {
  /** Token */
  token: string | null;
  /** 用户信息 */
  userInfo: UserInfo | null;
  /** 角色列表 */
  roles: RoleInfo[];
  /** 登录是否过期 */
  sessionTimeout: boolean;
  /** 最后登录时间 */
  lastUpdateTime: Date | null;
}

/** 用户状态 */
export const useUserStore = defineStore("app-user", () => {
  //#region [state]
  const state = reactive<UserState>({ userInfo: null, token: null, roles: [], sessionTimeout: false, lastUpdateTime: null });
  //#endregion

  //#region [getters]
  const getToken = computed(() => state.token || tokenCache.get());
  const getUserInfo = computed(() => state.userInfo || userInfoCache.get());
  //#endregion

  //#region [actions]
  /** 设置Token */
  const setToken = (t: string) => {
    state.token = t;
    tokenCache.set(t);
  };
  /** 设置用户信息 */
  const setUserInfo = (info: UserInfo) => {
    state.userInfo = info;
    state.lastUpdateTime = new Date();
    userInfoCache.set(info);
  };
  /** 重置所有状态 */
  const resetState = () => {
    state.userInfo = null;
    state.token = "";
    state.roles = [];
    state.sessionTimeout = false;
  };
  /** 登录 */
  const login = async (username: string, password: string) => {
    const token = await apiLogin.login({ username, password });
    if (token.value) {
      setToken(token.value);
      const params = new URLSearchParams(window.location.search);
      const redirect = params.get("redirect") || "/";
      await router.push(redirect);
    }
  };
  /** 登出 */
  const logout = async (goLogin = false) => {
    await apiLogin.logout();
    resetState();
    tokenCache.clear();
    userInfoCache.clear();
    goLogin && router.push({ name: "login" });
  };
  //#endregion

  return {
    ...toRefs(state),
    getToken,
    getUserInfo,
    setToken,
    setUserInfo,
    resetState,
    login,
    logout,
  };
});

/** 用户状态 (在setup方法外使用此方法) */
export const useUserStoreWithOut = () => {
  return useUserStore(store);
};
